home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*__________________________________________________________________
- |
- | blixscore_io.c - part of blixscore.c
- |
- | these routines are not in blixscore.c, because they are used
- | by the blixserver program too.
- |
- | (c) 1994 Frans van Hoesel, hoesel@chem.rug.nl
- | Xtreme Graphics Software
- |
- */
-
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <limits.h>
- #include <dirent.h>
-
- #include "blixscore_io.h"
-
- int sginap(long ticks);
-
- /*__________________________________________________________________
- |
- | write_data - write a data block
- |
- | a block of data is written, preceeded with is length
- | when length is negative, only the data is written.
- |
- */
-
- int write_data(int f, void *lbuf, int len) {
-
- int result;
- int leng;
- char *buf;
-
- buf = (char *)lbuf;
-
- if (len >= 0) {
- if (write(f, &len, 4) != 4)
- return -1;
- } else {
- len = -len;
- }
- leng = len;
- while (len > 0) {
- if (len > 512) {
- result = write(f, buf, 512);
- } else {
- result = write(f, buf, len);
- }
- len -=result;
- buf += result;
- if (result <= 0)
- return -1;
- }
- return leng;
- }
-
- /*__________________________________________________________________
- |
- | read_data - read a data block
- |
- | first the length of the block is read, then the data block with that
- | length. a negative value of maxlength implies a read, without the
- | preceeding length being read, but instead reads exactly -maxlen bytes
- */
-
- int read_data(int f, void *lbuf, int maxlen) {
-
- int len, leng;
- int result;
- char *buf;
-
- buf = (char *)lbuf;
- if (maxlen >= 0) {
- leng = 4;
- while (leng > 0) {
- result = read(f, buf, leng);
- if (result <= 0 ) {
- return -1;
- }
- leng -= result;
- buf += result;
- }
- len = *((int *)lbuf);
- buf = (char *)lbuf;
- if (len > maxlen) { /* protocol error */
- fprintf(stderr, "protocol error: got length %d "
- "expected at most %d\n", len, maxlen);
- return -1;
- }
- } else {
- len = -maxlen;
- }
- if (len > 100000) {
- /* obviously no image is this large, or it would be rejected
- * anyway (max size is 100 x 100)
- */
- return -1;
- }
- leng = len;
- while (len > 0) {
- if (len > 512) {
- result = read(f, buf, 512);
- } else {
- result = read(f, buf, len);
- }
- if (result <= 0) {
- return -1;
- }
- len -= result;
- buf += result;
- }
- return leng;
- }
-
-
- /*__________________________________________________________________
- |
- | readstr - read a string
- |
- | read a string; limit the length of the string to 127, so you
- | can read the result in an array of know size; and appends a
- | '\0' at the end of the string;
- |
- */
-
- int readstr(int f, char *s) {
- int len;
- len = read_data(f, s, 127);
- if (len >= 0) {
- *(s+len) = '\0';
- } else {
- /* create an empty string */
- *s = '\0';
- }
- return len;
- }
-
-
- /*__________________________________________________________________
- |
- | writestr - write a string
- |
- */
-
- int writestr(int f, char *s) {
- if (s == NULL )
- return (write_data(f, "", strlen("")));
- else
- return (write_data(f, s, strlen(s)));
- }
-
-
- /*__________________________________________________________________
- |
- | openscore - open the file with score
- |
- | this opens and locks the file that contains the high scores.
- | file locking is done so more than one game may be running at
- | any time. This is particulary true for the server side of
- | the world wide highscores, but may also effect your system
- | high score list.
- | the timeout value is a float number and gives the timeout
- | in seconds.
- | If the file does not exists,it is created, but left empty.
- |
- */
-
- int openscore(const char *path, float timeout) {
- int f;
- int retry;
-
- errno = 0;
- f = open(path, O_RDWR | O_CREAT, 0666);
- /* my guess is that the next test will always fail (f is always
- * set, but just in case)
- */
- retry = 0;
- if (f == -1 && (errno == EAGAIN || errno == EACCES)) {
- while (f == -1 && (errno == EAGAIN || errno == EACCES) &&
- retry < timeout * 10) {
- sginap(CLK_TCK/10);
- retry++;
- f = open(path, O_RDWR | O_CREAT, 0666);
- }
- }
- if (f != -1) {
- /* lock the file */
- retry = 0;
- while (lockf(f, F_TLOCK, 0) != 0 && retry < timeout &&
- (errno == EAGAIN || errno == EACCES )) {
- retry++;
- errno = 0;
- sginap(CLK_TCK/10);
- }
- if (retry >= timeout || errno == EAGAIN || errno == EACCES) {
- close(f);
- f = -1;
- }
- }
- return f;
- }
-
- /*__________________________________________________________________
- |
- | readscore - read the score list
- |
- | if the list does not exists, a default one is created.
- |
- */
-
- int readscore(int f, scorelist_t *scorelist) {
-
- char tmpstr[128];
- int i;
-
- tmpstr[0] = '\0';
- if (f == -1 || readstr(f,tmpstr) <= 0 || strncmp(tmpstr, "BLIX", 4)) {
- scorelist->game = 0;
- scorelist->id = 1;
- for (i=0; i<7; i++) {
- strcpy(scorelist->names[i], "Blix");
- strcpy(scorelist->hosts[i], "Xtreme Graphics Software");
- scorelist->images[i][0] = '\0';
- scorelist->scores[i] = 2000 - i * 250;
- scorelist->addrs[i] = 0;
- }
- } else {
- read_data(f, &(scorelist->game), sizeof(long));
- read_data(f, &(scorelist->id), sizeof(long));
- for (i=0; i<7; i++) {
- readstr(f, tmpstr);
- strcpy(scorelist->names[i], tmpstr);
- readstr(f, tmpstr);
- strcpy(scorelist->hosts[i], tmpstr);
- readstr(f, tmpstr);
- strcpy(scorelist->images[i], tmpstr);
- read_data(f, &(scorelist->scores[i]), sizeof(long));
- read_data(f, &(scorelist->addrs[i]), sizeof(long));
- }
- }
- return 0;
- }
-
- /*__________________________________________________________________
- |
- | writescore - write the score list
- |
- */
-
- void writescore(int f, scorelist_t *scorelist) {
- int i;
-
- if (f == -1)
- return;
- writestr(f, "BLIX");
- write_data(f, &(scorelist->game), sizeof(long));
- write_data(f, &(scorelist->id), sizeof(long));
- for (i=0; i< 7; i++) {
- writestr(f, scorelist->names[i]);
- writestr(f, scorelist->hosts[i]);
- writestr(f, scorelist->images[i]);
- write_data(f, &(scorelist->scores[i]), sizeof(long));
- write_data(f, &(scorelist->addrs[i]), sizeof(long));
- }
- }
-
- void cleanup_images(scorelist_t *scorelist, char *dirnam, char *ext) {
-
- DIR *dirp;
- struct dirent *dp;
- int found;
- int i;
- char tmpstr[512];
- char c;
-
- dirp = opendir(dirnam);
- if (dirp == NULL)
- return;
- while ((dp = readdir(dirp)) != NULL) {
- c = *(dp->d_name);
- if (c >= '0' && c <= '9' && strstr(dp->d_name, ext)) {
- /* see if this image is in the list; if not unlink it */
- found = 0;
- for (i=0; i< 7; i++) {
- if (scorelist->images[i] != NULL &&
- strstr(scorelist->images[i], dp->d_name) != NULL)
- found = 1;
- }
- if (found == 0) {
- strcpy(tmpstr, dirnam);
- strcat(tmpstr, "/");
- strcat(tmpstr, dp->d_name);
- unlink(tmpstr);
- }
- }
- }
- closedir(dirp);
- }
-